package com.learn.controller;

import com.learn.apis.PayFeignApi;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author DJJ_F
 * @version 1.0
 * @date 2025/08/01
 * @description ch07 断路器
 */
@RestController
public class OrderCircuitController {
    @Resource
    private PayFeignApi payFeignApi;

    @GetMapping("/order/circuit/{id}")
    @CircuitBreaker(name = "cloud-payment-service", fallbackMethod = "myFallBack")
    public String circuit(@PathVariable("id") Integer id) {
        return payFeignApi.circuit(id);
    }


    @GetMapping("/order/bulkhead/{id}")
    @Bulkhead(name = "cloud-payment-service",
            fallbackMethod = "myFallBack",
            type = Bulkhead.Type.SEMAPHORE)
    public String bulkhead(@PathVariable("id") Integer id) {
        return payFeignApi.circuit(id);
    }

    /**
     * 使用线程池要关闭分组
     * 在这个方法里面sleep是为了占用线程，模拟实现超时的结果
     * 在payFeignApi.circuit(id)方法里面sleep是无效的
     * 因为openFeign会新开一个线程
     * @param id
     * @return
     */
    @GetMapping("/order/pool/{id}")
    @Bulkhead(name = "cloud-payment-service",
            fallbackMethod = "myBulkheadPoolFallback",
            type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<String> pool(@PathVariable("id") Integer id) {
        System.out.println(Thread.currentThread().getName() + "\t" + "enter the method!!!");
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "\t" + "exist the method!!!");

        return CompletableFuture.supplyAsync(() -> payFeignApi.circuit(id) + "\t" + " Bulkhead.Type.THREADPOOL");
    }

    public String myFallBack(Integer id, Throwable t) {
        return "fallback method..........." + t.getMessage();
    }

    public CompletableFuture<String> myBulkheadPoolFallback(Integer id,Throwable t)
    {
        return CompletableFuture.supplyAsync(() -> "Bulkhead.Type.THREADPOOL，系统繁忙，请稍后再试-----/(ㄒoㄒ)/~~");
    }

    @GetMapping("/order/rate/{id}")
    @RateLimiter(name = "cloud-payment-service",
            fallbackMethod = "myFallBack")
    public String rateLimiter(@PathVariable("id") Integer id) {
        return payFeignApi.circuit(id);
    }
}
